package com.terminee.threads;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.terminee.model.ClientTerm;
import com.terminee.utils.TermineeUtils;

/**
 * Thread responsible for setting up and making all requests to backend
 * 
 * @author potlow
 * 
 */
public class BackendThread extends Thread {

	public enum BackendThreadModes { RetrieveResults, SubmitDefinition };
	
	public enum BackendThreadMessages { SearchSuccessful, NoResultsFound, TroubleGettingResults, SubmitSuccessful, TroubleSubmittingDefinition }

	// mode in which the thread should function in
	private BackendThreadModes mode;

	// Handler for communicating back with regular thread
	private Handler handler;

	// Bundle for obtaining extra parameter
	private Map<String, Object> extraParams;

	public BackendThread(Handler handler, BackendThreadModes mode, Map<String, Object> extraParams) {
		this.extraParams = extraParams;
		this.mode = mode;
		this.handler = handler;
	}

	@Override
	public void run() {

		switch (this.mode) {
		case RetrieveResults:
			retrieveResults();
			break;
		case SubmitDefinition:
			submitDefiniton();
			break;
		default:
			break;
		}

	}
		
	/**
	 * Get local results of buzzword
	 */
	private void retrieveResults() {
		
		// get Uri Builder, and url parameters
		Uri.Builder uriBuilder = (Uri.Builder)extraParams.get("uriBuilder");
		
		List<ClientTerm> clientTerms;
		try {
			String jsonString = TermineeUtils.getResponseFromURL(uriBuilder);
			
			Gson gson = new Gson();
			Type collectionType = new TypeToken<List<ClientTerm>>(){}.getType();
			clientTerms = gson.fromJson(jsonString, collectionType);
		} catch (Exception e) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.TroubleGettingResults);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
		
		if(clientTerms.size() == 0) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.NoResultsFound);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
			
		Message toMain = handler.obtainMessage();
		Bundle bundle = new Bundle();
		bundle.putSerializable("message type", BackendThreadMessages.SearchSuccessful);
		toMain.setData(bundle);
		toMain.obj = clientTerms;
		handler.sendMessage(toMain);
	}

	private void submitDefiniton() {
		// get Uri Builder, and url parameters
		Uri.Builder uriBuilder = (Uri.Builder)extraParams.get("uriBuilder");
		String json = (String)extraParams.get("json");
		
		String addSuccessful;
		try {
			addSuccessful = TermineeUtils.postStringToURL(uriBuilder, json);
		} catch (Exception e) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.TroubleSubmittingDefinition);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
		
		if(addSuccessful.equalsIgnoreCase("false")) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.TroubleSubmittingDefinition);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
		
		Message toMain = handler.obtainMessage();
		Bundle bundle = new Bundle();
		bundle.putSerializable("message type", BackendThreadMessages.SubmitSuccessful);
		toMain.setData(bundle);
		handler.sendMessage(toMain);
	}
	
}
